package com.ics.cmsadmin.frame.utils;

import com.ics.cmsadmin.frame.core.DateProperty;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by Sandwich on 2018-07-14
 */
public final class CalendarUtil {


    /**
     * 获取 当前日期"年月日"的秒数
     *
     * @return
     */
    public static Long getCurrYMDSeconds() {
        String currTime = dateToStr(new Date(), CalendarUtil.TimeFormat.yyyy_MM_dd);
        Date currDate = strToDate(currTime, CalendarUtil.TimeFormat.yyyy_MM_dd);
        return currDate.getTime() / 1000;
    }

    /**
     * 获取 当前日期"年月日时分秒"的秒数
     *
     * @return
     */
    public static Long getCurrSeconds() {
        String currTime = dateToStr(new Date(), TimeFormat.yyyy_MM_dd__HH_mm_ss);
        Date currDate = strToDate(currTime, CalendarUtil.TimeFormat.yyyy_MM_dd__HH_mm_ss);
        return currDate.getTime() / 1000;
    }

    /**
     * 获取当前日期毫秒数
     *
     * @return
     */
    public static Long getCurrMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 计算两个日期之间相差的天数(如果两个日期是一天则返回0)
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDaysBetween(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return -1;
        } else if (startDate.equals(endDate)) {
            return 0;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        start.setTime(startDate);
        end.setTime(endDate);

        //设置时间为0时
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 0);
        end.set(Calendar.SECOND, 0);
        //得到两个日期相差的天数

        int days = ((int) (end.getTime().getTime() / 1000) - (int) (start.getTime().getTime() / 1000)) / 3600 / 24;
        return days;
    }

    /**
     * 获取两个日期之间相差的秒数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getSecondsBetween(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return -1;
        } else if (startDate.equals(endDate)) {
            return 0;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        start.setTime(startDate);
        end.setTime(endDate);

        //设置时间为0时
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 0);
        end.set(Calendar.SECOND, 0);
        //得到两个日期相差的秒数

        int seconds = ((int) (end.getTime().getTime() / 1000) - (int) (start.getTime().getTime() / 1000) / 3600);
        return seconds;
    }

    /**
     * 获取两个日期之间相差的分数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getMinuteBetween(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return -1;
        } else if (startDate.equals(endDate)) {
            return 0;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        start.setTime(startDate);
        end.setTime(endDate);

        //设置时间为0时
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 0);
        end.set(Calendar.SECOND, 0);
        //得到两个日期相差的分数

        int minute = ((int) (endDate.getTime() / 1000) - (int) (startDate.getTime() / 1000)) / 60;
        return minute;
    }

    /**
     * 返回某个日期属于一个星期的周几(起始天是周日)
     * 1-周一
     * 2-周二
     * 3-周三
     * 4-周四
     * 5-周五
     * 6-周六
     * 7-周日
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.SUNDAY);
        c.setTime(date);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        return dayOfWeek == 0 ? 7 : dayOfWeek;
    }

    /**
     * 把一个字符串转换为日期,字符串的格式规定为:年-月-日
     *
     * @param dateStr
     * @return
     */
    public static Date fromSimpleDateStr(String dateStr) {
        Date d = null;
        try {
            d = getSimpleFormat().parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }

    /**
     * 获取简单时间格式(年-月-日)
     *
     * @return
     */
    private static DateFormat getSimpleFormat() {
        return getFormat(TimeFormat.yyyy_MM_dd.getTimeFormat());
    }

    private static DateFormat getFormat(String format) {
        return new SimpleDateFormat(format);
    }

    /**
     * 获取当前时间的mysql标准datetime格式字符串
     *
     * @return
     */
    public static String toMySqlDateStrOfNow() {
        return toMySqlDateStr(new Date());
    }

    /**
     * 把一个日期格式化成mysql日期,格式为: yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @return
     */
    public static String toMySqlDateStr(Date date) {
        return getMySqlDateFormat().format(date);
    }

    /**
     * 获取标准日期格式(年-月-日 时:分:秒): yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    private static DateFormat getMySqlDateFormat() {
        return getFormat(TimeFormat.yyyy_MM_dd__HH_mm_ss.getTimeFormat());
    }

    /**
     * 把一个日期转换成字符串,格式为: yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String toSimpleDateStr(Date date) {
        return getSimpleFormat().format(date);
    }

    /**
     * 根据给定格式,把日期转换成字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateToStr(Date date, TimeFormat format) {
        return getFormat(format.toString()).format(date);
    }

    /**
     * 根据给定格式,把字符串转换为日期
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static Date strToDate(String dateStr, TimeFormat format) {
        Date d = null;
        try {
            d = getFormat(format.toString()).parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }

    /**
     * @param dataStr
     * @return
     */
    public static String getTimeDesc(String dataStr) {
        Date tobeTran = CalendarUtil.strToDate(dataStr, TimeFormat.yyyy_MM_dd__HH_mm_ss);

        //得到两个日期相差的秒数

        int seconds = ((int) (new Date().getTime() / 1000) - (int) (tobeTran.getTime() / 1000));
        String timeStr = "";
        if (seconds < 60) {
            timeStr = "刚刚";
        } else if (seconds < 60 * 60) {
            int min = seconds / 60;
            timeStr = min + "分钟前";
        } else if (seconds < 60 * 60 * 24) {
            int hour = seconds / (60 * 60);
            timeStr = hour + "小时前";
        } else if (seconds < 60 * 60 * 24 * 7) {
            int day = seconds / (60 * 60 * 24);
            if (day <= 1) {
                timeStr = "昨天";
            } else {
                timeStr = day + "天前";
            }
        } else if (seconds < 60 * 60 * 24 * 31) {
            int weekend = seconds / (60 * 60 * 24 * 7);
            timeStr = weekend + "周前";
        } else {
            timeStr = CalendarUtil.toSimpleDateStr(tobeTran);
        }
        return timeStr;
    }

    /**
     * 调整时间,返回调整结果
     *
     * @param time
     * @param field
     * @param offset
     * @return
     */
    public static String getTimeOffset(String time, Field field, int offset) {
        if (StringUtils.isEmpty(time)) {
            return null;
        } else if (time.matches("^\\d{4}-\\d{2}-\\d{2}\\s{1}\\d{2}:\\d{2}:\\d{2}$") == false) {
            return null;
        } else {
            Date d = null;
            try {
                d = fromMySqlFormat(time);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            d = getTimeOffset(d, field, offset);
            return toMySqlDateStr(d);
        }
    }

    /**
     * 调整时间,返回调整结果
     *
     * @param field
     * @param offset
     * @return
     */
    public static String getTimeStr(Field field, int offset) {
        Date d = getTimeOffset(new Date(), field, offset);
        return toMySqlDateStr(d);
    }

    public static Date getTimeOffset(Date d, Field field, int offset) {
        if (Field.valueOf(field.getValue()) == null) {
            return d;// 为空,不操作
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        c.add(field.getValue(), offset);
        return c.getTime();
    }

    public static Date getTimeOffset(Field field, int offset) {
        return getTimeOffset(new Date(), field, offset);
    }

    /**
     * 从一个mysql字符串格式化成日期
     *
     * @param dateStr
     * @return
     */
    public static Date fromMySqlFormat(String dateStr) {
        Date d = null;
        try {
            d = getMySqlDateFormat().parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }

    public static int getYear(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.YEAR);
    }

    public static int getMonth(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.MONTH) + 1;
    }

    public static int getDayOfMonth(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static int getHourOfDay(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    public static int getMinute(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.MINUTE);
    }

    public static int getSecond(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.SECOND);
    }

    public static int getMilliSecond(Date d) {
        if (d == null) {
            return -1;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c.get(Calendar.MILLISECOND);
    }

    public static DateProperty getDateProps(Date d) {
        if (d == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(d);

        DateProperty di = new DateProperty(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND));

        return di;
    }

    public static String simplified(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) return "";
        return dateStr.trim().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "");
    }

    /**
     * 将一个字符串
     *
     * @param dateStr
     * @param fromFormat
     * @param toFormat
     * @return
     */
    public static String formatDateStr(String dateStr, TimeFormat fromFormat, TimeFormat toFormat) {
        Date d = strToDate(dateStr, fromFormat);
        return dateToStr(d, toFormat);
    }

    public enum TimeFormat {
        HH_mm_ss("HH:mm:ss"),
        HH_mm("HH:mm"),
        mm_ss("mm:ss"),
        HHmmss("HHmmss"),
        HHmm("HHmm"),
        HH("HH"),
        mmss("mmss"),
        mm("mm"),
        ss("ss"),
        yyyy_MM_dd__HH_mm_ss("yyyy-MM-dd HH:mm:ss"),
        yyyy_MM_dd__HH_mm("yyyy-MM-dd HH:mm"),
        yyyy_MM_dd__HH("yyyy-MM-dd HH"),
        yyyyMMddHHmmss("yyyyMMddHHmmss"),
        yyyyMMddHHmm("yyyyMMddHHmm"),
        yyyyMMddHH("yyyyMMddHH"),
        yyyyMMdd("yyyyMMdd"),
        yyyy_MM_dd("yyyy-MM-dd"),
        yyyy_MM("yyyy-MM"),
        yyyy_M_d("yyyy-M-d"),
        yyyyMM("yyyyMM"),
        yyyy_slash_MM("yyyy/MM"),
        yyyy("yyyy"),
        MM("MM"),
        dd("dd");

        private String format;

        TimeFormat(String format) {
            this.format = format;
        }

        public static TimeFormat forFormat(String format) {
            for (TimeFormat c : values()) {
                if (c.toString().equals(format)) {
                    return c;
                }
            }
            return null;
        }

        public String toString() {
            return this.format;
        }

        public String getTimeFormat() {
            return this.format;
        }
    }

    /**
     * 内部的枚举类型
     */
    public enum Field {
        SECONDS(Calendar.SECOND, "seconds"),// 秒
        MINUTE(Calendar.MINUTE, "minute"),// 分
        HOUR(Calendar.HOUR_OF_DAY, "hour"),// 时
        DAY(Calendar.DAY_OF_MONTH, "day"),// 天
        WEEK(Calendar.WEEK_OF_YEAR, "week_of_year"),// 周
        MONTH(Calendar.MONTH, "month"),// 月
        YEAR(Calendar.YEAR, "year");// 年

        private int value;
        private String description;

        Field(int value, String content) {
            this.value = value;
            this.description = content;
        }

        public static Field valueOf(int field) {
            for (Field f : Field.values()) {
                if (f.getValue() == field) {
                    return f;
                }
            }
            return null;
        }

        public int getValue() {
            return this.value;
        }

        public String getDescription() {
            return this.description;
        }

        public Field setType(int value) {
            this.value = value;
            return this;
        }
    }

    public static void main(String[] args) {
    }

}
